home *** CD-ROM | disk | FTP | other *** search
- /* cryptsum.c -- copyright 1992 by C.D.Lane */
-
- #include <c.h>
- #include <libc.h>
- #include <ctype.h>
- #include <stdio.h>
-
- #include "cryptsum.h"
-
- #define RANGE (127)
- #define MAXUSHORT ((unsigned short) 0x8000)
-
- union overlay { unsigned short halfword; char salt[2]; };
-
- char *cs_cryptkey(const char *key, unsigned short checksum)
- {
- union overlay u_sum;
-
- u_sum.halfword = checksum;
-
- if(!isalpha(u_sum.salt[0] &= RANGE)) u_sum.salt[0] = ((u_sum.salt[0] * ('z' - 'a')) / RANGE) + 'a';
- if(!isalpha(u_sum.salt[1] &= RANGE)) u_sum.salt[1] = ((u_sum.salt[1] * ('Z' - 'A')) / RANGE) + 'A';
-
- return(crypt((char *) key, u_sum.salt) + sizeof(u_sum));
- }
-
- char *cs_tablelookup(const char *segment, const char *section, const char *table)
- {
- static char key[BUFSIZ];
-
- (void) sprintf(key, "%s %s", segment, section);
-
- while(table != NULL && *table != '\0' && strncmp(key, table, strlen(key)) != 0)
- if((table = index(table, '\n')) != NULL) table++;
-
- if(table == NULL || *table == '\0' || (table = index(table + strlen(key), ' ')) == NULL) return(NULL);
-
- return((char *) ++table);
- }
-
- unsigned short cs_checksum(unsigned short checksum, unsigned char byte)
- {
- return(byte ^ ((checksum << 1) | ((checksum & MAXUSHORT) != 0)));
- }
-
- int cs_checkkey(const char *segment, const char *section, const char *key)
- {
- int i, size;
- void *pointer;
- unsigned short halfword = 0;
- char *password, *encrypted, table[MAXBSIZE];
-
- if((pointer = getsectdata(segment, section, &size)) == NULL) return(CS_NOSECTION);
-
- for(i = 0; i < size; i++) halfword = cs_checksum(halfword, *((unsigned char *) pointer++));
-
- if((pointer = getsectdata(CS_SEGMENT, CS_SECTION, &size)) == NULL) return(CS_NOCHECKSUM);
-
- (void) strcat(strncpy(table, (char *) pointer, MIN(size, MAXBSIZE - 1)), "");
-
- if((encrypted = cs_tablelookup(segment, section, table)) == NULL) return(CS_NOENTRY);
-
- password = cs_cryptkey(key, halfword);
-
- if(strncmp(password, encrypted, strlen(password)) != 0) return(CS_NOMATCH);
-
- return(CS_SUCCESS);
- }